package br.com.velp.sudecap.daoimpl;

import br.com.velp.sudecap.dao.DireitoUsuarioDAO;
import br.com.velp.sudecap.entidade.DireitoSistema;
import br.com.velp.sudecap.entidade.DireitoUsuario;
import br.com.velp.sudecap.entidade.GrupoUsuario;
import br.com.velp.sudecap.entidade.Usuario;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

/**
 * <sumario>
 * <objetivo> "Rastreabilidade" </objetivo>
 * <autor> EDUARDO SANTOS DE OLIVEIRA </autor>
 * <versao>1.0.0.0</versao>
 * <data_criacao> 17.10.2012 </data_criacao>
 * <data_ultima_alteracao> N/A </data_ultima_alteracao>
 * <requisitos_afetados> RF010.03 – Gerenciar Permissão de Usuários / RF010.04 - Gerenciar de Grupo de Usuários </requisitos_afetados>
 * <descricao> Interface Responsável Por Operações Interentes ao Contexto de 
 *             Controle de Acesso à Aplicação</descricao>
 * </sumario>
 */
@Repository("direitoUsuarioDAO")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class DireitoUsuarioDAOImpl implements DireitoUsuarioDAO{
    
    public static final Long serialVersionUID = 1L;
    
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public Long salvar(DireitoUsuario value) {
	Long id = (Long) sessionFactory.getCurrentSession().save(value);
	sessionFactory.getCurrentSession().flush();
	return id;
    }

    @Override
    public void atualizar(DireitoUsuario value) {
	sessionFactory.getCurrentSession().update(value);
	sessionFactory.getCurrentSession().flush();
    }

    @Override
    public DireitoUsuario obterPorId(Long id) {
	return (DireitoUsuario) sessionFactory.getCurrentSession().get(DireitoUsuario.class, id);
    }

    @Override
    public void excluir(DireitoUsuario value) {
	sessionFactory.getCurrentSession().delete(value);
	sessionFactory.getCurrentSession().flush();
    }

    @Override
    public List<DireitoUsuario> recuperarDireitosUsuario(Usuario usuario) {
	
	StringBuilder consulta = new StringBuilder();
	
	consulta.append(" select direitoUsuario from DireitoUsuario direitoUsuario ");
	consulta.append(" left join direitoUsuario.grupo grupo ");
	consulta.append(" left join direitoUsuario.direito direito ");
	consulta.append(" where direitoUsuario.usuario = :usuario ");
	
	Query query = sessionFactory.getCurrentSession().createQuery(consulta.toString());
	query.setParameter("usuario", usuario);
	
	return query.list();
	
    }

    @Override
    public List<GrupoUsuario> recuperarTodosGrupos() {
	return sessionFactory.getCurrentSession().createCriteria(GrupoUsuario.class).addOrder(Order.asc("nome")).list();
    }

    @Override
    public List<DireitoSistema> recuperarTodosDireitosSistema() {
	return sessionFactory.getCurrentSession().createCriteria(DireitoSistema.class).addOrder(Order.asc("descricao")).list();
    }
    
    @Override
    public List<Usuario> recuperarTodosUsuarios(){
	return sessionFactory.getCurrentSession().createCriteria(Usuario.class).addOrder(Order.asc("login")).list();
    }
    
    @Override
    public void removerDireitoUsuario(Usuario usuario, DireitoSistema direito){
	String delete = "delete from DireitoUsuario where direito = :direito and usuario = :usuario";
	sessionFactory.getCurrentSession()
		.createQuery(delete)
		.setParameter("direito", direito)
		.setParameter("usuario", usuario)
		.executeUpdate();
	sessionFactory.getCurrentSession().flush();
    }
    
    @Override
    public void removerDireitoUsuario(Usuario usuario, GrupoUsuario grupo){
	String delete = "delete from DireitoUsuario where grupo = :grupo and usuario = :usuario";
	sessionFactory.getCurrentSession()
		.createQuery(delete)
		.setParameter("grupo", grupo)
		.setParameter("usuario", usuario)
		.executeUpdate();
	sessionFactory.getCurrentSession().flush();
    }
    
    @Override
    public boolean usuarioContemDireito(Usuario usuario, DireitoSistema direito){
	String consulta = "select count(id) from DireitoUsuario "
			+ "where usuario = :usuario and direito = :direito";
	Query query = sessionFactory.getCurrentSession().createQuery(consulta);
	query.setParameter("usuario", usuario);
	query.setParameter("direito", direito);
	return ((Long) query.uniqueResult()) > 0;
    }
    
    @Override
    public boolean usuarioContemGrupo(Usuario usuario, GrupoUsuario grupo){
	String consulta = "select count(id) from DireitoUsuario "
			+ "where usuario = :usuario and grupo = :grupo";
	Query query = sessionFactory.getCurrentSession().createQuery(consulta);
	query.setParameter("usuario", usuario);
	query.setParameter("grupo", grupo);	
	return ((Long) query.uniqueResult()) > 0;
    }
    
}
